package main

import "fmt"

// 对命令进行定义,不需要知道命令的实现细节，只需要知道命令对象即可
type Command interface {
	Execute()
}

type PowerCommand struct {
	tv TV
}

func (c *PowerCommand) Execute() {
	c.tv.PowerPress()
}

type VolumeUpCommand struct {
	tv TV
}

func (c *VolumeUpCommand) Execute() {
	c.tv.VolumeUp()
}

// 创建命令执行者（控制面板）,只需要添加命令执行即可
type ControlPanel struct {
	commands []Command
}

func (c *ControlPanel) AddCommand(cmd Command) {
	c.commands = append(c.commands, cmd)
}
func (c *ControlPanel) ExecuteCommands() {
	for _, cmd := range c.commands {
		cmd.Execute()
	}
}

// 定义接收者（TV）接口，由接收者接收命令并执行具体逻辑
type TV interface {
	PowerPress()
	VolumeUp()
}

type RealTV struct {
	name   string
	power  bool
	volume int
}

func (t *RealTV) PowerPress() {
	if t.power {
		t.power = false
		fmt.Printf("关闭%s电视\n", t.name)
	} else {
		t.power = true
		fmt.Printf("打开%s电视\n", t.name)
	}
}

func (t *RealTV) VolumeUp() {
	if t.power {
		t.volume++
		fmt.Printf("当前音量%d\n", t.volume)
	}
}

func main() {
	tv := &RealTV{
		name:   "Philips",
		power:  false,
		volume: 20,
	}
	controlPanel := &ControlPanel{}
	controlPanel.AddCommand(&PowerCommand{tv: tv})
	controlPanel.AddCommand(&VolumeUpCommand{tv: tv})
	controlPanel.AddCommand(&VolumeUpCommand{tv: tv})
	controlPanel.AddCommand(&PowerCommand{tv: tv})
	controlPanel.ExecuteCommands()
}
